package com.itheima.reggie.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.reggie.common.BaseContext;
import com.itheima.reggie.common.CustomException;
import com.itheima.reggie.entity.*;
import com.itheima.reggie.mapper.OrderMapper;
import com.itheima.reggie.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * @version 1.0
 * @Author 杨旭康
 * @Date 2022/11/2 23:24
 * @question:
 */

@Service
@Slf4j
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Orders> implements OrderService {

    @Autowired
    private ShoppingCartService shoppingCartService;
    @Autowired
    private OrderDetailService orderDetailService;
    @Autowired
    private UserService userService;
    @Autowired
    private AddressBookService addressBookService;

    /**
     * 用户下单
     * 前台传来的数据有 地址id 支付方式 备注
     * @param orders
     */
    @Override
    @Transactional //开启事务
    public void submit(Orders orders) {

        //首先获取下单人的id
        Long userId = BaseContext.getCurrentId();
        //获取用户详情信息,并调用service查询
        User user = userService.getById(userId);

        //获取用户的购物车数据,并调用service查询
        LambdaQueryWrapper<ShoppingCart> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ShoppingCart::getUserId,userId);
        List<ShoppingCart> shoppingCartList = shoppingCartService.list(queryWrapper);
        if (shoppingCartList == null && shoppingCartList.size() == 0) {
            throw new CustomException("购物车中无数据,不能下单!");
        }

        //获取用户的地址信息,并调用service查询
        Long addressBookId = orders.getAddressBookId();
        AddressBook addressBook = addressBookService.getById(addressBookId);
        if (addressBook == null) {
            throw new CustomException("没有查询到用户的地址信息,不能下单!");
        }

        //开始进行对,订单合订单详情表的赋值
        //首先对订单详情表进行赋值(可能有多条数据),订单表中有总的金额

        //使用雪花算法提前生成订单id
        long orderId = IdWorker.getId();
        //AtomicInteger 使用原子计数器 避免在多线程情况下计算的金额出现差错
        AtomicInteger amount = new AtomicInteger(0);

        //数据在购物车中-->遍历取出
        List<OrderDetail> orderDetailList = shoppingCartList.stream().map((item) -> {
            //创建一个空的 订单明细 对象
            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setOrderId(orderId);
            orderDetail.setNumber(item.getNumber());
            orderDetail.setDishFlavor(item.getDishFlavor());
            orderDetail.setDishId(item.getDishId());
            orderDetail.setSetmealId(item.getSetmealId());
            orderDetail.setName(item.getName());
            orderDetail.setImage(item.getImage());
            orderDetail.setAmount(item.getAmount());
            //使用原子计数器的累加算法进行计算金额
            amount.addAndGet(item.getAmount().multiply(new BigDecimal(item.getNumber())).intValue());

            return orderDetail;
        }).collect(Collectors.toList());
        //向订单明细表插入数据，多条数据
        orderDetailService.saveBatch(orderDetailList);

        //组装订单数据
        orders.setId(orderId);
        orders.setOrderTime(LocalDateTime.now());
        orders.setCheckoutTime(LocalDateTime.now());
        orders.setStatus(2);
        orders.setAmount(new BigDecimal(amount.get()));//总金额
        orders.setUserId(userId);
        orders.setNumber(String.valueOf(orderId));
        orders.setUserName(user.getName());
        orders.setConsignee(addressBook.getConsignee());
        orders.setPhone(addressBook.getPhone());
        orders.setAddress((addressBook.getProvinceName() == null ? "" : addressBook.getProvinceName())
                + (addressBook.getCityName() == null ? "" : addressBook.getCityName())
                + (addressBook.getDistrictName() == null ? "" : addressBook.getDistrictName())
                + (addressBook.getDetail() == null ? "" : addressBook.getDetail()));
        //向订单表插入数据，一条数据
        this.save(orders);

        //清空购物车数据
        shoppingCartService.remove(queryWrapper);

    }

    /**
     * 再来一单
     * 1.用户id无需再获得
     * 2.需要更改之前的订单号
     * (订单号 id 可以设置成一个 此处必须设置id 对应订单明细)
     * @param orders
     */
    @Override
    public void saveAgain(Orders orders) {

        //重新生成新的订单号
        long newOrderId = IdWorker.getId();

        //从前端获取之前的数据 从而获得之前的订单
        LambdaQueryWrapper<Orders> queryWrapper = new LambdaQueryWrapper<>();
        //使用 id号 和订单号进行等值查询
        queryWrapper.eq(Orders::getNumber,orders.getId());
        Orders order = this.getOne(queryWrapper);

        //因为数据值已经在用户下单当中保存了下来 所以只需改个别即可
        //订单号 id号 状态 下单时间 结账时间  重新设置
        order.setId(newOrderId);
        order.setNumber(String.valueOf(newOrderId));
        order.setStatus(2);
        order.setOrderTime(LocalDateTime.now());
        order.setCheckoutTime(LocalDateTime.now());

        //保存订单数据
        this.save(order);

        LambdaQueryWrapper<OrderDetail> wrapper = new LambdaQueryWrapper<>();
        //通过订单的 id 来获取集合
        wrapper.eq(OrderDetail::getOrderId,orders.getId());
        //调用service
        List<OrderDetail> orderDetailList = orderDetailService.list(wrapper);

        //遍历设置数据
        orderDetailList = orderDetailList.stream().map((item) -> {
            //将订单明细的 商品 id设置成空等自动生成
            item.setId(null);
            item.setOrderId(newOrderId);

            return item;
        }).collect(Collectors.toList());

        //调用service保存
        orderDetailService.saveBatch(orderDetailList);

    }


}
